`define SIMU_USE_PLL 0 //set 0 to speed up simulation

module soc_lite_top #(parameter SIMULATION=1'b0)(
        input         resetn, 
        input         clk,

        //------gpio-------
        output [15:0] led,
        output [1 :0] led_rg0,
        output [1 :0] led_rg1,
        output [7 :0] num_csn,
        output [6 :0] num_a_g,
        input  [7 :0] switch, 
        output [3 :0] btn_key_col,
        input  [3 :0] btn_key_row,
        input  [1 :0] btn_step
    );
    
    //debug signals
    wire [31:0] debug_wb_pc;
    wire [3 :0] debug_wb_rf_wen;
    wire [4 :0] debug_wb_rf_wnum;
    wire [31:0] debug_wb_rf_wdata;

    //clk and resetn
    wire        cpu_clk;
    wire        timer_clk;
    reg         cpu_resetn;
    always @(posedge cpu_clk)
    begin
        cpu_resetn <= resetn;
    end
    generate if(SIMULATION && `SIMU_USE_PLL==0)
    begin: speedup_simulation
        assign cpu_clk   = clk;
        assign timer_clk = clk;
    end
    else
    begin: pll
        clk_pll clk_pll
        (
            .clk_in1 (clk),
            .cpu_clk (cpu_clk),
            .timer_clk (timer_clk)
        );
    end
    endgenerate

    //cpu inst sram
    wire        cpu_inst_en;
    wire [3 :0] cpu_inst_wen;
    wire [31:0] cpu_inst_addr;
    wire [31:0] cpu_inst_wdata;
    wire [31:0] cpu_inst_rdata;
    //cpu data sram
    wire        cpu_data_en;
    wire [3 :0] cpu_data_wen;
    wire [31:0] cpu_data_addr;
    wire [31:0] cpu_data_wdata;
    wire [31:0] cpu_data_rdata;

    //data sram
    wire        data_sram_en;
    wire [3 :0] data_sram_wen;
    wire [31:0] data_sram_addr;
    wire [31:0] data_sram_wdata;
    wire [31:0] data_sram_rdata;
    //conf
    wire        conf_en;
    wire [3 :0] conf_wen;
    wire [31:0] conf_addr;
    wire [31:0] conf_wdata;
    wire [31:0] conf_rdata;

    //cpu
    openmips cpu(
        .clk              (~cpu_clk   ),
        .resetn           (~cpu_resetn),  //low active  // rst即为resetn
        .int              (6'd0      ),  //interrupt,high active

        .inst_sram_en     (cpu_inst_en   ),
        .inst_sram_wen    (cpu_inst_wen  ),
        .inst_sram_addr   (cpu_inst_addr ),
        .inst_sram_wdata  (cpu_inst_wdata),
        .inst_sram_rdata  (cpu_inst_rdata),
        
        .data_sram_en     (cpu_data_en   ),
        .data_sram_wen    (cpu_data_wen  ),
        .data_sram_addr   (cpu_data_addr ),
        .data_sram_wdata  (cpu_data_wdata),
        .data_sram_rdata  (cpu_data_rdata),

        //debug
        .debug_wb_pc      (debug_wb_pc      ),
        .debug_wb_rf_wen  (debug_wb_rf_wen  ),
        .debug_wb_rf_wnum (debug_wb_rf_wnum ),
        .debug_wb_rf_wdata(debug_wb_rf_wdata)
    );

    //inst ram
    inst_ram inst_ram
    (
        .clka  (cpu_clk            ),   
        .ena   (cpu_inst_en        ),
        .wea   (cpu_inst_wen       ),   //3:0
        .addra (cpu_inst_addr[19:2]),   //17:0
        .dina  (cpu_inst_wdata     ),   //31:0
        .douta (cpu_inst_rdata     )    //31:0
    );

    bridge_1x2 bridge_1x2(
        .clk             ( cpu_clk         ), // i, 1                 
        .resetn          ( cpu_resetn      ), // i, 1                 

        .cpu_data_en     ( cpu_data_en     ), // i, 4                 
        .cpu_data_wen    ( cpu_data_wen    ), // i, 4                 
        .cpu_data_addr   ( cpu_data_addr   ), // i, 32                
        .cpu_data_wdata  ( cpu_data_wdata  ), // i, 32                
        .cpu_data_rdata  ( cpu_data_rdata  ), // o, 32                

        .data_sram_en    ( data_sram_en    ), // o, 4                 
        .data_sram_wen   ( data_sram_wen   ), // o, 4                 
        .data_sram_addr  ( data_sram_addr  ), // o, `DATA_RAM_ADDR_LEN
        .data_sram_wdata ( data_sram_wdata ), // o, 32                
        .data_sram_rdata ( data_sram_rdata ), // i, 32                

        .conf_en         ( conf_en         ), // o, 1                 
        .conf_wen        ( conf_wen        ), // o, 4                 
        .conf_addr       ( conf_addr       ), // o, 32                
        .conf_wdata      ( conf_wdata      ), // o, 32                
        .conf_rdata      ( conf_rdata      )  // i, 32                
    );

    //data ram
    data_ram data_ram
    (
        .clka  (cpu_clk             ),   
        .ena   (data_sram_en        ),
        .wea   (data_sram_wen       ),   //3:0 这玩意儿是写使能，当遇到load指令的时候要是全0才行�?
        .addra (data_sram_addr[17:2]),   //15:0
        .dina  (data_sram_wdata     ),   //31:0
        .douta (data_sram_rdata     )    //31:0
    );

    //confreg
    confreg #(.SIMULATION(SIMULATION)) confreg
    (
        .clk         ( cpu_clk    ),  // i, 1   
        .timer_clk   ( timer_clk  ),  // i, 1   
        .resetn      ( cpu_resetn ),  // i, 1    
        .conf_en     ( conf_en    ),  // i, 1      
        .conf_wen    ( conf_wen   ),  // i, 4      
        .conf_addr   ( conf_addr  ),  // i, 32        
        .conf_wdata  ( conf_wdata ),  // i, 32         
        .conf_rdata  ( conf_rdata ),  // o, 32         
        .led         ( led        ),  // o, 16   
        .led_rg0     ( led_rg0    ),  // o, 2      
        .led_rg1     ( led_rg1    ),  // o, 2      
        .num_csn     ( num_csn    ),  // o, 8      
        .num_a_g     ( num_a_g    ),  // o, 7      
        .switch      ( switch     ),  // i, 8     
        .btn_key_col ( btn_key_col),  // o, 4          
        .btn_key_row ( btn_key_row),  // i, 4           
        .btn_step    ( btn_step   )   // i, 2   
    );

endmodule

